package com.zhiche.lisa.bms.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.parser.ISqlParser;
import com.baomidou.mybatisplus.plugins.parser.tenant.TenantHandler;
import com.zhiche.lisa.core.supports.BaseException;
import com.zhiche.lisa.core.utils.HttpClientUtil;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * Created by qichao on 2017/12/10.
 */
@Configuration
@MapperScan("com.zhiche.lisa.bms.dao.mapper*")
public class MybatisPlusConfig {

    @Value("${account.info-uri}")
    private String GET_ACCOUNT_INFO_URI;

    @Value("${filterTable}")
    private String fiterTable;

    private static final String GET_ACCOUNT_INFO_PATH = "/uaa/account/getAccount";

    @Value("${permission.getsharingrule}")
    private String GET_TENANT_SHARING_RULE_URI;

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setLocalPage(true);// 开启 PageHelper 的支持
        return paginationInterceptor;
    }

    @Bean
    public TenantQueryInterceptor tenantQueryInterceptor() {
        TenantQueryInterceptor tenantQueryInterceptor = new TenantQueryInterceptor();
        List<ISqlParser> sqlParserList = new ArrayList<>();
        CustomTenantSqlParser customTenantSqlParser = new CustomTenantSqlParser();
        customTenantSqlParser.setTenantHandler(new TenantHandler() {
            @Override
            public Expression getTenantId() {
                if (Objects.isNull(SecurityContextHolder.getContext()
                        .getAuthentication())) {
                    throw new BaseException("无用户信息，请先登录验证！");
                }
                Object user = SecurityContextHolder.getContext()
                        .getAuthentication().getPrincipal();
                Boolean isAuthenticated = SecurityContextHolder.getContext()
                        .getAuthentication().isAuthenticated();
                if (Objects.isNull(user) || isAuthenticated.equals(false) || user.toString().equals("anonymousUser")) {
                    throw new BaseException("无用户信息，请先登录认证！");
                } else {
                    /**
                     * 获取租户ID
                     */
                    List<NameValuePair> urlParameters = new ArrayList<>();
                    urlParameters.add(new BasicNameValuePair("identifier", user.toString()));
                    try {
                        JSONObject obj = JSON.parseObject(HttpClientUtil.get(GET_ACCOUNT_INFO_URI +
                                GET_ACCOUNT_INFO_PATH, urlParameters, 10000));
                        JSONObject retData = obj.getJSONObject("data");
                        String tenantId = retData.getString("tenantId");
                        /**
                         * 根据租户ID获取租户数据共享规则
                         */
                        List<NameValuePair> ruleParam = new ArrayList<>();
                        ruleParam.add(new BasicNameValuePair("tenantId", tenantId));
                        JSONObject ruleObj = JSON.parseObject(HttpClientUtil.get
                                (GET_TENANT_SHARING_RULE_URI,
                                        ruleParam, 10000));
                        String ret = ruleObj.getString("data");
                        return new StringValue(ret);
                    } catch (Exception ex) {
                        throw new BaseException(ex.getMessage());
                    }
                }
            }

            @Override
            public String getTenantIdColumn() {
                return "tenant_id";
            }

            @Override
            public boolean doTableFilter(String tableName) {
                List<String> fiterTables = Arrays.asList(fiterTable.trim().replace(" ", "").split(";|\n"));
                if (fiterTables.contains(tableName)) {
                    return true;
                }
                return false;
            }
        });

        sqlParserList.add(customTenantSqlParser);
        tenantQueryInterceptor.setSqlParserList(sqlParserList);
        return tenantQueryInterceptor;
    }
}
